package com.zw.admin.server.service.impl;

import com.zw.admin.server.dao.StrategyDao;
import com.zw.admin.server.dao.StrategyDeviceDao;
import com.zw.admin.server.model.Strategy;
import com.zw.admin.server.model.StrategyDevice;
import com.zw.admin.server.service.DeviceService;
import com.zw.admin.server.service.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 定时策略任务执行Bean类
 */
@Slf4j
@Service
public class TaskServiceImpl implements TaskService {

    @Autowired
    StrategyDao strategyDao;
    @Autowired
    StrategyDeviceDao strategyDeviceDao;
    @Autowired
    DeviceService deviceService;

    /**
     * 遍历查询策略表下所有绑定设备,
     * 根据策略的开关类型，起止时间范围，星期，和当前时间,
     * 控制是否调用设备开关接口
     */
    @Override
    public void doStrategys() {
        log.info("--- quatz 定时任务 doStrategys 执行 ---");
        List<Strategy> strategies = strategyDao.selectAll();
        Calendar calendar = Calendar.getInstance();
        if(calendar == null){
            log.error("doStrategys Calendar getInstance return is null ");
        }
        int curWeek = calendar.get(Calendar.DAY_OF_WEEK);
        strategies.forEach(strategy -> dealStrategy(strategy,curWeek,calendar) );
    }

    /**
     * 处理单个策略
     * @param strategy
     */
    private void dealStrategy(Strategy strategy,int curWeek,Calendar calendar) {
        if(strategy == null){
            log.error("dealStrategy strategy is null ！");
            return;
        }
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        String weeks = strategy.getWeeks();
        String startTime = strategy.getStartTime();
        String endTime = strategy.getEndTime();
        if(StringUtils.isBlank(startTime)){
            log.error("dealStrategy this strategy weeks startTime");
            return;
        }
        if(StringUtils.isBlank(endTime)){
            log.error("dealStrategy this strategy weeks endTime");
            return;
        }

        String[] starts = startTime.split(":");
        String[] ends = endTime.split(":");

        calendar.set(year,month,day,Integer.valueOf(starts[0]),Integer.valueOf(starts[1]),Integer.valueOf(starts[2]));
        Date start = calendar.getTime();
        calendar.set(year,month,day,Integer.valueOf(ends[0]),Integer.valueOf(ends[1]),Integer.valueOf(ends[2]));
        Date end = calendar.getTime();

        if(StringUtils.isBlank(weeks)){
            log.error("dealStrategy this strategy weeks isBlank");
            return;
        }
        List<String> weekList = Arrays.asList(weeks.split(","));
        if(!weekList.contains(String.valueOf(curWeek))){
            //判断当前星期未在有效范围,不执行后续逻辑
            return;
        }
        Integer strategyId = strategy.getStrategyId();
        log.info("dealStrategy weekList contains curWeek strategy_id begin next : {}",strategyId);
        log.info("执行策略，策略有效星期:{}",weeks);
        log.info("执行策略，起始时间:{}",start);
        log.info("执行策略，起始时间:{}",end);
        //查询指定策略下绑定的设备列表
        List<StrategyDevice> strategyDevices = strategyDeviceDao.selectByStrategyId(strategyId);
        strategyDevices.forEach(strategyDevice -> dealDeviceOnOff(strategyDevice,start,end));

    }

    /**
     * @param strategyDevice
     */
    private void dealDeviceOnOff(StrategyDevice strategyDevice, Date start,Date end) {
        String deviceId = strategyDevice.getDeviceId();
        if (StringUtils.isBlank(deviceId)){
            log.error("dealDeviceOnOff strategyDevice deviceId is blank");
        }
        long startTime = start.getTime();
        long endTime = end.getTime();
        long currentTimeMillis = System.currentTimeMillis();
        if(currentTimeMillis > startTime && currentTimeMillis < endTime){
            //当前时间在策略时间范围内 执行开
            deviceService.updateDeviceStates(deviceId, "1");
        }else{
            deviceService.updateDeviceStates(deviceId, "0");
        }
    }
}
